package kr.co.bicycle;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;

import kr.co.bicycle.data.BicycleInfo;
import kr.co.bicycle.data.OverlayData;
import kr.co.bicycle.data.PathPoint;
import kr.co.bicycle.data.CourseData;
import kr.co.bicycle.data.TraceData;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 *	SQLiteOpenHelper 재정의 클래스
 *	데이터 베이스를 생성해주는 클래스로 안드로이드에서는 
 *	내부적으로 초경량 디비인 Sqlite를 사용
 *	SQLiteOpenHelper를 상속받아 처리하면 각 앱마다 file 형태의
 *	데이터베이스가 생성된다.
 */
public class DBHelper extends SQLiteOpenHelper {
	public static final int DB_VER = 1;											// 디비버젼
	public static final String DB_FILE = "bicycle.db";							// 디비파일이음
	public static final String BICYCLE_TABLE = "bicycle_table";				// 위치저장 테이블
	public static final String INFO_TABLE = "info_table";						// 자전거 정보 테이블
	public static final String OVERLAY_TABLE = "overlay_table";			// 오버레이 테이블	
	public static final String TRACE_COORD_TABLE = "trace_coord";		// 이동좌표 테이블
	public static final String COURSE_TABLE = "course";						// 코스 테이블
	
	public DBHelper(final Context context){
		super(context, DB_FILE, null, DB_VER);
	}

	/** 디비 생성시 테이블을 만들어준다. */
	@Override
	public void onCreate(final SQLiteDatabase db) {	// db가 생성될때 테이블도 생성
		// TODO Auto-generated method stub
		//  자전거 코스정보를 담을 테이블
		String sql = "CREATE TABLE "+ INFO_TABLE +" (no INTEGER PRIMARY KEY," +
				     "  title TEXT NOT NULL, contents TEXT NOT NULL );";
		db.execSQL(sql);
		
		// 지도상에 표시할 오버레이정보를 담을 테이블
		sql = "CREATE TABLE "+ OVERLAY_TABLE +" (no INTEGER PRIMARY KEY," +
			     "  title TEXT NOT NULL" +				// 타이틀
			     "	,snippet TEXT NOT NULL" +			// 내용
			     " ,lat TEXT NOT NULL" +					// 위도
			     " ,lng TEXT NOT NULL " +				// 경도
			     " ,img INTEGER NOT NULL " +			// 이미지
			     " ,type TEXT );";								// 마커 타입		
		db.execSQL(sql);		// sql 실행
		

		// 운동 기록 테이블
		sql = "CREATE TABLE running_record (idx INTEGER PRIMARY KEY,"
				+ " date TEXT NOT NULL, " + // 날짜
				" distance TEXT NOT NULL, " + // 이동거리
				" starPlace TEXT NULL, " + // 출발위치
				" endPlace TEXT NULL, " + // 도착위치
				" cal INTEGER DEFAULT 0 NOT NULL, " + // 소비 칼로리
				" goalCal INTEGER DEFAULT 0 NOT NULL " + // 목표 칼로리
				");";
		db.execSQL(sql);

		// 이동 위치 저장 테이블
		sql = "CREATE TABLE " + TRACE_COORD_TABLE + " (" + 
				" title TEXT NOT NULL, " + // 제목 
				" latitude TEXT NOT NULL, " + // 위도
				" longitude TEXT NOT NULL, " + // 경도
				" dateMillis TEXT, " +				 // 기록 시간
				" distance TEXT, " +				 // 총거리
				" flag TEXT" + // 출발 혹은 도착 플레그"
				");";
		db.execSQL(sql);		
		
		// 코스 테이블
		sql = "CREATE TABLE " + COURSE_TABLE + " (" + 
				" idx INTEGER PRIMARY KEY," + 
				" title TEXT NOT NULL, " + // 제목 
				" latitude TEXT NOT NULL, " + // 위도
				" longitude TEXT NOT NULL, " + // 경도
				" level TEXT " +			 // 레벨
				");";
		db.execSQL(sql);				
	}

	@Override
	public void onOpen(final SQLiteDatabase db) {
		// TODO Auto-generated method stub
		super.onOpen(db);
	}

	@Override
	public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
		// sqlite가 업그레이드 됐을경우 이전에 있던 테이블은 없앤다.
        db.execSQL("DROP TABLE IF EXISTS "+ INFO_TABLE);
        onCreate(db);
	}
	
	/**
	 *  자전거 정보 데이터 insert
	 * @param data
	 */
	public static void insertData(DBHelper dbhelper, BicycleInfo data){
		// 디비에 일정 저장 처리
		SQLiteDatabase db = dbhelper.getWritableDatabase(); // 쓰기모도로 해주자
		ContentValues cv = new ContentValues();				// 컨텐츠벨류를 이용하여 데이터 insert ,update 처리를 한다.
		cv.put("title", data.getTitle());
		cv.put("contents", data.getContents());		
		db.insert(DBHelper.INFO_TABLE, null, cv);		// 테이블에 저장
		db.close();											// 디비는 반드시 닫아준다.
		dbhelper.close();
	}	
	
	/**
	 * 지도에 표시할 오버레이 데이터들
	 * @param dbhelper
	 * @param data
	 */
	public static void insertData(DBHelper dbhelper, OverlayData data){
		// 디비에 일정 저장 처리
		SQLiteDatabase db = dbhelper.getWritableDatabase(); // 쓰기모도로 해주자
		ContentValues cv = new ContentValues();					// 컨탠츠밸류를 통해 데이터를 삽입한다.
		cv.put("lat", data.getLat());	
		cv.put("lng", data.getLng());
		cv.put("title", data.getTitle());
		cv.put("snippet", data.getSnippet());
		cv.put("img", data.getImageRs());
		db.insert(DBHelper.OVERLAY_TABLE, null, cv);	// 테이블에 저장
		db.close();											// 디비는 반드시 닫아준다.
		dbhelper.close();
	}		
	
	/**
	 * 이동경로 좌표 저장
	 * @param dbhelper
	 * @param data
	 */
	public static void insertTracePointData(DBHelper dbhelper, String title, PathPoint data){
		// 디비에 일정 저장 처리
		SQLiteDatabase db = dbhelper.getWritableDatabase(); // 쓰기모도로 해주자
		ContentValues cv = new ContentValues();					// 컨탠츠밸류를 통해 데이터를 삽입한다.
		cv.put("title", title);	
		cv.put("latitude", data.getLatitude());	
		cv.put("longitude", data.getLongitude());
		cv.put("dateMillis", data.getDate());
		cv.put("flag", data.getPathFlag());
		db.insert(DBHelper.TRACE_COORD_TABLE, null, cv);	// 테이블에 저장
		db.close();													// 디비는 반드시 닫아준다.
	}		
	

	
	/**
	 * 총거리 저장
	 * @param dbhelper
	 * @param data
	 */
	public static void updateDistnace(DBHelper dbhelper, String title, String distance){
		// 디비에 일정 저장 처리
		SQLiteDatabase db = dbhelper.getWritableDatabase(); // 쓰기모도로 해주자
		ContentValues cv = new ContentValues();					// 컨탠츠밸류를 통해 데이터를 삽입한다.
		cv.put("distance", distance);	
		db.update(DBHelper.TRACE_COORD_TABLE, cv, "title = ?", new String[]{title, });
		db.close();													
	}		
	
	/**
	 * 운동내역 목록을 가져온다.
	 * 
	 * @return
	 */
	public ArrayList<TraceData> selectRunningList() {
		SQLiteDatabase db = this.getReadableDatabase();
		Cursor cursor = db.rawQuery(		// 직접 쿼리문을 이용하여 내용을 가져온다.
				"SELECT * FROM running_record ORDER BY idx DESC", null);
		ArrayList<TraceData> list = null;
		if (cursor.moveToFirst()) {			// 커서의 처음으로 이동
			list = new ArrayList<TraceData>();
			do {
				TraceData data = new TraceData();
				// 커서에서 내용을 가져온후 컬랙선에 담는다.
				int index = cursor.getInt(cursor.getColumnIndex("idx"));
				data.setIndex(index);
				String date = cursor.getString(cursor.getColumnIndex("date"));
				String distance = cursor.getString(cursor
						.getColumnIndex("distance"));
				String startPlace = cursor.getString(cursor
						.getColumnIndex("starPlace"));
				String endPlace = cursor.getString(cursor
						.getColumnIndex("endPlace"));
				int cal = cursor.getInt(cursor.getColumnIndex("cal"));

				data.setDate(date);
				data.setDistance(distance);
				data.setStartPlace(startPlace);
				data.setEndPlace(endPlace);
				data.setCal(cal);
				list.add(data);		// 컬랙션에 데이터를 넣자
			} while (cursor.moveToNext());		// 다음 쿼리로 이동
		}
		return list;
	}


	/**
	 * 자전거이동목록 불러와 내역을 리스트로 반환
	 * 
	 * @return
	 */
	public ArrayList<PathPoint> selectExercusePath(String title) {
		SQLiteDatabase db = this.getReadableDatabase();
		Cursor cursor = db
				.rawQuery(
						"SELECT * FROM " + TRACE_COORD_TABLE + " WHERE title = ? ORDER BY dateMillis ASC ",
						new String[] { title, });
		ArrayList<PathPoint> list = null;
		if (cursor.moveToFirst()) {
			list = new ArrayList<PathPoint>();
			do {
				PathPoint data = new PathPoint();
				String flag = cursor.getString(cursor.getColumnIndex("flag"));
				String latitude = cursor.getString(cursor.getColumnIndex("latitude"));		// 위도 
				String longitude = cursor.getString(cursor.getColumnIndex("longitude"));	// 경도 
				String dateMillis = cursor.getString(cursor.getColumnIndex("dateMillis"));	// 운동시각
				
				data.setDate(dateMillis);
				data.setLatitude(Double.valueOf(latitude));
				data.setLongitude(Double.valueOf(longitude));
				data.setPathFlag(flag);
				list.add(data);
			} while (cursor.moveToNext());
		}
		return list;
	}	
	
	/**
	 * 운동 기록 하기
	 * 
	 * @param data
	 * @return
	 */
	public int insertRunning(TraceData data) {
		int result;
		SQLiteDatabase db = this.getWritableDatabase();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy년 MM월 dd일", Locale.KOREA);// 날짜 포맷

		// 날짜가 이미 있으면 업데이트로 변경
		SQLiteDatabase rDb = this.getReadableDatabase();
		Cursor cursor = rDb.rawQuery(
				"SELECT * FROM running_record WHERE date = ?",
				new String[] { sdf.format(new Date()), });
		ContentValues cv = new ContentValues();
		cv.put("date", sdf.format(new Date()));
		cv.put("distance", data.getDistance());
		cv.put("starPlace", data.getStartPlace());
		cv.put("endPlace", data.getEndPlace());
		cv.put("cal", data.getCal());
		// 커서가 있으면 이전 내용이 있거나 목표치가 있으므로 업데이트로
		if (cursor.moveToFirst()) {
			result = (int) db.update("running_record", cv, "date = ?",
					new String[] { sdf.format(new Date()), });
		} else {
			result = (int) db.insert("running_record", null, cv);
		}
		return result;
	}	
	
	
	
	/**
	 * 코스 등록
	 * @param data		코스데이터
	 */
	public static void insertCourse(DBHelper dbhelper, CourseData data) {
		// 디비에 일정 저장 처리
		SQLiteDatabase db = dbhelper.getWritableDatabase(); // 쓰기모도로 해주자
		ContentValues cv = new ContentValues();					// 컨탠츠밸류를 통해 데이터를 삽입한다.
		cv.put("title",  data.getTitle());	
		cv.put("latitude", data.getLat());	
		cv.put("longitude", data.getLng());
		cv.put("level", data.getLevel());
		db.insert(DBHelper.COURSE_TABLE, null, cv);	// 테이블에 저장
		db.close();		
	}		
	

	/**
	 * 인덱스로 오버레이 아이템 정보 조회
	 * @param index
	 */
	public static OverlayData selectOverlayData(Context context, String index){
		// 디비에 일정 저장 처리
		DBHelper dbhelper = new DBHelper(context);
		SQLiteDatabase db = dbhelper.getReadableDatabase(); // 읽기모도로 해주자
		Cursor cursor = db.query(OVERLAY_TABLE, null, "no = ?", new String[]{index, }, null, null, null);
		OverlayData data = null;
		if(cursor.moveToFirst()){
				data = new OverlayData();		// 데이터를 bean 담는다
				data.setIndex(Integer.valueOf(cursor.getInt(cursor.getColumnIndex("no"))));
				data.setSnippet(cursor.getString(cursor.getColumnIndex("snippet")));
				data.setTitle(cursor.getString(cursor.getColumnIndex("title")));
				data.setImageRs(cursor.getInt(cursor.getColumnIndex("img")));
		}
		db.close();							// 디비는 반드시 닫아준다.
		dbhelper.close();
		return data;
	}		
	
	/**
	 * 코스 목록을 가져온다.
	 * @return
	 * 		코스목록 컬랙션
	 */
	public static ArrayList<CourseData> selectCourseList(Context context) {
		DBHelper dbhelper = new DBHelper(context);
		SQLiteDatabase db = dbhelper.getReadableDatabase();
		Cursor cursor = db.rawQuery(		// 직접 쿼리문을 이용하여 내용을 가져온다.
				"SELECT * FROM " + COURSE_TABLE + " group by title" , null);		// 코스명별로 가져온다.
		ArrayList<CourseData> list = new ArrayList<CourseData>();
		if (cursor.moveToFirst()) {			// 커서의 처음으로 이동
			do {
				CourseData data = new CourseData();
				// 커서에서 내용을 가져온후 컬랙선에 담는다.
				String title = cursor.getString(cursor.getColumnIndex("title"));
				String level = cursor.getString(cursor.getColumnIndex("level"));
				
				data.setTitle(title);
				data.setLevel(level);
				list.add(data);					// 컬랙션에 데이터를 넣자
			} while (cursor.moveToNext());		// 다음 쿼리로 이동
		}
		db.close();
		dbhelper.close();
		
		return list;
	}	
	
	/**
	 * 코스 목록을 가져온다.
	 * @return
	 * 		코스목록 컬랙션
	 */
	public static ArrayList<CourseData> selectCourse(Context context, String courseTitle) {
		DBHelper dbhelper = new DBHelper(context);
		SQLiteDatabase db = dbhelper.getReadableDatabase();
		Cursor cursor = db.rawQuery(		// 직접 쿼리문을 이용하여 내용을 가져온다.
				"SELECT * FROM " + COURSE_TABLE + " WHERE title = '" + courseTitle + "' order by idx asc" , null);		// 코스명별로 가져온다.
		ArrayList<CourseData> list = new ArrayList<CourseData>();
		String title, level, latitude, longitude;
		if (cursor.moveToFirst()) {			// 커서의 처음으로 이동
			do {
				CourseData data = new CourseData();
				// 커서에서 내용을 가져온후 컬랙선에 담는다.
				title = cursor.getString(cursor.getColumnIndex("title"));
				level = cursor.getString(cursor.getColumnIndex("level"));
				latitude = cursor.getString(cursor.getColumnIndex("latitude"));		// 위도 
				longitude = cursor.getString(cursor.getColumnIndex("longitude"));	// 경도 
				data.setTitle(title);
				data.setLevel(level);
				data.setLat(latitude);
				data.setLng(longitude);
				list.add(data);					// 컬랙션에 데이터를 넣자
			} while (cursor.moveToNext());		// 다음 쿼리로 이동
		}
		db.close();
		dbhelper.close();
		
		return list;
	}		
}
